/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package conection;

import chat.Chat;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author javi
 */
public class Servidor implements Runnable {

    ServerSocket socketServidor;
    Socket socketCliente;
    DataInputStream entradaServidor, entradaChatServidor;
    DataOutputStream salidaServidor, salidaChatServidor;
    HashMap<String, Socket> conexionesAbiertas;
    Runnable hiloChatCliente;
    Thread hiloCliente;

    public Servidor(int puerto) throws IOException {
        socketServidor = new ServerSocket(puerto);
        conexionesAbiertas = new HashMap();
    }

    public void aceptarConexion() throws IOException {
        socketCliente = socketServidor.accept();
        entradaServidor = new DataInputStream(socketCliente.getInputStream());
        salidaServidor = new DataOutputStream(socketCliente.getOutputStream());
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    procesarPeticion();
                } catch (IOException ex) {
                    Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }).start();
    }

    private void procesarPeticion() throws IOException {
        //Se manda al cliente un mensaje de login
        salidaServidor.writeUTF("Login:");
        salidaServidor.flush();
        String nuevoNickCliente = entradaServidor.readUTF();
        if (nuevoNickCliente.isEmpty() || nuevoNickCliente == null) {
            salidaServidor.writeUTF("log|0");
            salidaServidor.flush();
        } else {
            System.out.println("Recibido cliente: " + nuevoNickCliente);
            if (comprobarNombre(nuevoNickCliente, socketCliente)) {
                salidaServidor.writeUTF("log|1");
                salidaServidor.flush();
                comienzaChat(nuevoNickCliente);
            } else {
                salidaServidor.writeUTF("log|0");
                salidaServidor.flush();
            }
        }
    }

    private synchronized boolean comprobarNombre(String nuevoCliente, Socket socketNuevoCliente) {
        if (conexionesAbiertas.containsKey(nuevoCliente)) {
            return false;
        } else {
            conexionesAbiertas.put(nuevoCliente, socketNuevoCliente);
            return true;
        }
    }

    private void comienzaChat(String nuevoNickCliente) throws IOException {
        Chat chatCliente = new Chat(conexionesAbiertas, socketCliente, nuevoNickCliente, this);
        chatCliente.start();

    }

    public void desconectarCliente(String clienteADesconectar) throws IOException {
        synchronized(conexionesAbiertas){
            conexionesAbiertas.remove(clienteADesconectar);
            System.out.println("Se ha desconectado "+clienteADesconectar);
        }
        
        salidaServidor.close();
        entradaServidor.close();
        socketCliente.close();
    }

    @Override
    public void run() {
        try {
            while (true) {
                aceptarConexion();
            }
        } catch (IOException ex) {
            Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void main(String[] args) {
        try {

            Servidor servidorSocket = new Servidor(12345);
            Thread hiloServidor = new Thread(servidorSocket);
            hiloServidor.start();
        } catch (IOException ex) {
            Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}
